package com.mihuo.config;

import com.mihuo.config.interceptor.AuthInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;

/**
 * Spring MVC 核心配置类
 * <p>
 * 本类通过实现 {@link WebMvcConfigurer} 接口，用于自定义Spring MVC的配置，
 * 主要承担两大核心职责：
 * 1. <strong>注册并配置全局拦截器</strong>：为系统添加统一的身份认证、权限校验等切面逻辑。
 * 2. <strong>定制静态资源映射规则</strong>：确保Swagger等前端UI所需的静态资源能够被正确访问。
 * </p>
 * <p>
 * 通过 {@code addInterceptors} 方法，注册了自定义的认证拦截器，并排除了Swagger文档相关路径以避免拦截。
 * 通过 {@code addResourceHandlers} 方法，显式地映射了Swagger UI的HTML页面和WebJars静态资源的位置，解决了高版本Spring Boot中可能出现的资源访问问题。
 * </p>
 *
 * @author mihuo
 * @date 2025-09-29
 * @version 1.0
 * @see WebMvcConfigurer
 * @see AuthInterceptor
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Resource
    private AuthInterceptor handlerMethodPreInterceptor;

    /**
     * 配置拦截器注册
     *
     * 该方法用于注册自定义拦截器，并设置拦截路径和排除路径。
     * 拦截器按照配置顺序执行，主要用于实现权限验证、日志记录等通用功能。
     *
     * 执行流程说明：
     * 1. preHandle: 控制器方法执行前调用，返回true则放行，false则拦截
     * 2. postHandle: 控制器方法执行后调用，可对ModelAndView进行处理
     * 3. afterCompletion: 整个请求完成后调用，用于资源清理等操作
     *
     * 多个拦截器执行顺序：
     * - preHandle按配置顺序执行
     * - postHandle和afterCompletion按配置逆序执行
     * - 某个拦截器preHandle返回false时，该拦截器及之前拦截器的preHandle会执行，
     *   但postHandle都不会执行，只有之前拦截器的afterCompletion会执行[3,5](@ref)
     *
     * @param registry 拦截器注册器，用于添加和配置拦截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 定义需要排除的Swagger路径数组
        // 这些路径不需要经过权限验证拦截器，确保API文档可正常访问
        String[] swaggerExcludePaths = new String[]{
                "/swagger-ui.html",           // Swagger UI主页面
                "/swagger-resources/**",      // Swagger资源文件
                "/webjars/**",                // Webjars静态资源
                "/v2/api-docs",               // Swagger v2 API文档端点
                "/v3/api-docs",               // Swagger v3 API文档端点
                "/swagger**/**",              // 所有Swagger相关路径
                "/**/doc.html",               // Knife4j文档页面
                "/**/api-docs/**",            // 所有API文档端点
                "/static/**",                 //静态资源
                "/sys/quartz/**"              //定时任务管理接口
        };

        // 注册拦截器并配置拦截规则
        registry.addInterceptor(handlerMethodPreInterceptor)
                .addPathPatterns("/**")       // 拦截所有请求路径
                .excludePathPatterns(swaggerExcludePaths); // 排除Swagger相关路径
    }

    /**
     * 配置Swagger UI静态资源映射
     * 解决Spring Boot 2.6+版本可能出现的资源访问问题
     * 确保能够正常访问/swagger-ui.html页面
     * @param registry 资源处理器注册器
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}